package com.dandelion.api.manager;

import com.dandelion.api.request.ThirdCredentials;
import com.dandelion.common.dao.auto.pojo.ThirdUserBind;
import com.dandelion.common.dao.auto.pojo.UserAccount;
import com.dandelion.common.dao.auto.pojo.UserSession;
import com.dandelion.common.domain.AccessToken;
import com.dandelion.common.domain.UserProfile;
import com.dandelion.common.domain.WxUser;
import com.dandelion.common.service.ThirdUserBindService;
import com.dandelion.common.service.UserAccountService;
import com.dandelion.common.service.UserSessionService;
import com.dandelion.common.wx.WxLoginService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserAccountManager {

    @Autowired
    private WxLoginService wxLoginService;

    @Autowired
    private ThirdUserBindService thirdUserBindService;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private UserSessionService userSessionService;

    public void logout(String token) {
        if (StringUtils.isBlank(token)) {
            return;
        }

        userSessionService.expireUserSession(token);
    }

    @Transactional
    public AccessToken wxlogin(ThirdCredentials credentials) {
        // get wx user info and check access_token is valid or not
        WxUser user = wxLoginService.login(credentials.getJsCode());
        // check is already bound to an user account or not.
        ThirdUserBind bind = thirdUserBindService.selectByOpenid(user.getOpenid(), credentials.getPlatform().name());
        if (bind == null) {
            //create new user account
            UserAccount account = userAccountService.createNewUserAccount(user);

            //bind user account
            thirdUserBindService.bindUserAccount(account.getId(), credentials.getPlatform().name(), user.getOpenid(), user.getSessionKey());

            // insert new user session
            UserSession session = userSessionService.insertNewUserSession(account.getId());
            return toAccessToken(session);
        }

        //update user session
        thirdUserBindService.updateBindUserAccount(bind.getUserId(), user.getSessionKey());
        UserSession session = userSessionService.updateUserSession(bind.getUserId());
        session.setUserId(bind.getUserId());
        return toAccessToken(session);
    }

    private AccessToken toAccessToken(UserSession session) {
        AccessToken token = new AccessToken();
        token.setExpireTime(session.getExpireTime() == null ? 0 : session.getExpireTime().getTime());
        token.setUserId(session.getUserId());
        token.setUserToken(session.getUserToken());
        return token;
    }

    public AccessToken getUserAccessToken(String token) {
        UserSession session = userSessionService.getValidUserSessionByToken(token);
        return session != null ? toAccessToken(session) : null;
    }

    public UserProfile getUserProfile(long userId) {
        UserAccount account = userAccountService.getAccountById(userId);
        UserProfile profile = new UserProfile();
        profile.setAvatar(account.getAvatar());
        profile.setNickname(account.getNickname());
        profile.setUserId(String.valueOf(userId));
        return profile;
    }
}
